home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
BUFFERS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-01
|
4KB
|
136 lines
/* receive buffer allocation routines */
/* used to provide buffers that can be gotten at interrupt time */
#include "global.h"
#include "mbuf.h"
#include "buffers.h"
#if (defined(MSDOS) && !defined(MSC))
# include "alloc.h"
#endif
static unsigned max_rxbufs = 0; /* max number of rx bufs */
static unsigned min_bufsize = MINRXBUFSIZ; /* min size of buffers */
static unsigned max_bufsize = MAXRXBUFSIZ; /* max size of buffers */
unsigned cur_rxbufs = 0; /* number of pre-allocated rx bufs */
struct mbuf *sys_rxbufs = NULLBUF; /* list of pre-allocated buffers */
struct mbuf *sys_txfree = NULLBUF; /* list of buffers freed by transmitter */
/* "buffers" command sets the number of receive buffers */
int
dobuffers (argc,argv)
int argc;
char *argv[];
{
if (argc == 1)
printf("%u buffers of %u .. %u bytes\n",max_rxbufs,
min_bufsize,max_bufsize);
else{
max_rxbufs = atoi(argv[1]);
if (argc > 2)
min_bufsize = atoi(argv[2]);
if (argc > 3)
max_bufsize = atoi(argv[3]);
if (min_bufsize < 2)
min_bufsize = MINRXBUFSIZ;
if (max_bufsize < min_bufsize)
max_bufsize = min_bufsize;
}
buf_alloc(); /* alloc initial set of buffers */
return 0;
}
/* check if enough buffers are on the receive buffer list
* if not, allocate them and link to the list
* also, buffers on the tx "to be freed" list are freed
* malloc and free are only called with interrupts enabled,
* because overruns will occur during the free list scan...
*/
void
buf_alloc()
{
register struct mbuf *bp;
unsigned bufsize;
int i_state;
#if (defined(ATARI_ST) && defined(MWC))
struct memblock { /* MW C freelist structure */
long size;
struct memblock *next;
};
extern struct memblock *_a_scanp; /* current start of scan */
long blocksize;
#endif
#if (defined(MSDOS) && !defined(MSC))
extern HEADER PTR allocp; /* current start of scan */
unsigned blocksize;
#endif
while (sys_txfree != NULLBUF){ /* buffers to be freed */
i_state = disable();
bp = sys_txfree; /* unlink one buffer */
sys_txfree = bp->next;
restore(i_state);
free(bp); /* free it with ints enabled */
}
while (cur_rxbufs < max_rxbufs){
bufsize = max_bufsize; /* allocate maximum buffer */
/* this piece of code tries to minimize the free list fragmentation
* by taking a small block from the free list as a receive buffer.
* any block between MIN and MAX bufsize will be allocated, resulting
* in many exact fit allocations.
*/
#if (defined(ATARI_ST) && defined(MWC))
if (_a_scanp->size & 1) /* pointing to a free block? */
{
/* when free, check if next also free and join if so */
while ((blocksize = ((struct memblock *) ((char *) _a_scanp + _a_scanp->size - 1))->size) & 1)
{
/* join next (free) block with this one */
_a_scanp->size += blocksize - 1;
}
/* joined free blocks, now check if within limits */
/* compute blocksize = sizeof(free block) - sizeof(struct mbuf) */
blocksize = _a_scanp->size - 1 - sizeof(long) - sizeof(struct mbuf);
if (blocksize >= min_bufsize && /* big enough? */
blocksize <= max_bufsize) /* not too big? */
{
bufsize = (int) blocksize;
}
}
#endif
#if (defined(MSDOS) && !defined(MSC))
/* compute blocksize = sizeof(free block) - sizeof(struct mbuf) */
blocksize = allocp->s.size * sizeof(HEADER) - sizeof(HEADER) - sizeof(struct mbuf);
if (blocksize >= min_bufsize && /* big enough? */
blocksize <= max_bufsize) /* not too big? */
{
bufsize = blocksize;
}
#endif
if ((bp = alloc_mbuf(bufsize)) == NULLBUF)
break; /* no space, try again later */
i_state = disable();
bp->next = sys_rxbufs; /* link at head of chain */
sys_rxbufs = bp;
cur_rxbufs++;
restore(i_state);
}
}